#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>

typedef struct SegNode {
    int l, r, sum;
    bool lazytag;
} SegNode;

typedef struct SegTree {
    SegNode *arr;
    int arrSize;
} SegTree;

void build(SegTree *obj, int id, int l, int r, const int *nums) {
    obj->arr[id].l = l;
    obj->arr[id].r = r;
    obj->arr[id].lazytag = false;
    if (l == r) {
        obj->arr[id].sum = nums[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(obj, 2 * id, l, mid, nums);
    build(obj, 2 * id + 1, mid + 1, r, nums);
    obj->arr[id].sum = obj->arr[2 * id].sum + obj->arr[2 * id + 1].sum;
}

/* pushdown函数：下传懒标记，即将当前区间的修改情况下传到其左右孩子结点 */
void pushdown(SegTree *obj, int x) {
    if (obj->arr[x].lazytag) {
        obj->arr[2 * x].lazytag = !obj->arr[2 * x].lazytag;
        obj->arr[2 * x].sum = obj->arr[2 * x].r - obj->arr[2 * x].l + 1 - obj->arr[2 * x].sum;
        obj->arr[2 * x + 1].lazytag = !obj->arr[2 * x + 1].lazytag;
        obj->arr[2 * x + 1].sum = obj->arr[2 * x + 1].r - obj->arr[2 * x + 1].l + 1 - obj->arr[2 * x + 1].sum;
        obj->arr[x].lazytag = false;
    }
}

/* 区间修改 */
void modify(SegTree *obj, int id, int l, int r) {
    if (obj->arr[id].l >= l && obj->arr[id].r <= r) {
        obj->arr[id].sum = (obj->arr[id].r - obj->arr[id].l + 1) - obj->arr[id].sum;
        obj->arr[id].lazytag = !obj->arr[id].lazytag;
        return;
    }
    pushdown(obj, id);
    int mid = (obj->arr[id].l + obj->arr[id].r) >> 1;
    if (obj->arr[2 * id].r >= l) {
        modify(obj, 2 * id, l, r);
    }
    if (obj->arr[2 * id + 1].l <= r) {
        modify(obj, 2 * id + 1, l, r);
    }
    obj->arr[id].sum = obj->arr[2 * id].sum + obj->arr[2 * id + 1].sum;
}

/* 区间查询 */
int query(SegTree *obj, int id, int l, int r) {
    if (obj->arr[id].l >= l && obj->arr[id].r <= r) {
        return obj->arr[id].sum;
    }
    if (obj->arr[id].r < l || obj->arr[id].l > r) {
        return 0;
    }
    pushdown(obj, id);
    int res = 0;
    if (obj->arr[2 * id].r >= l) {
        res += query(obj, 2 * id, l, r);
    }
    if (obj->arr[2 * id + 1].l <= r) {
        res += query(obj, 2 * id + 1, l, r);
    }
    return res;
}

SegTree *createSegTree(const int *nums, int numsSize) {
    SegTree *obj = (SegTree *) malloc(sizeof(SegTree));
    obj->arrSize = 4 * numsSize + 1;
    obj->arr = (SegNode *) malloc(sizeof(SegNode) * obj->arrSize);
    build(obj, 1, 0, numsSize - 1, nums);
    return obj;
}

void freeSegTree(SegTree *obj) {
    free(obj->arr);
    free(obj);
}

int sumRange(SegTree *obj, int left, int right) {
    return query(obj, 1, left, right);
}

void reverseRange(SegTree *obj, int left, int right) {
    modify(obj, 1, left, right);
}

long long *
handleQuery(int *nums1, int nums1Size, int *nums2, int nums2Size, int **queries, int queriesSize, int *queriesColSize,
            int *returnSize) {
    int n = nums1Size;
    int m = queriesSize;
    SegTree *tree = createSegTree(nums1, nums1Size);
    long long sum = 0;
    for (int i = 0; i < n; i++) {
        sum += nums2[i];
    }
    long long *ans = (long long *) malloc(sizeof(long long) * m);
    int pos = 0;
    for (int i = 0; i < m; i++) {
        if (queries[i][0] == 1) {
            int l = queries[i][1];
            int r = queries[i][2];
            reverseRange(tree, l, r);
        } else if (queries[i][0] == 2) {
            sum += (long long) sumRange(tree, 0, n - 1) * queries[i][1];
        } else if (queries[i][0] == 3) {
            ans[pos++] = sum;
        }
    }
    *returnSize = pos;
    freeSegTree(tree);
    return ans;
}

int main() {
    int nums1[3] = {1, 0, 1}, nums2[3] = {0, 0, 0}, queries[3][3] = {1, 1, 1, 2, 1, 0, 3, 0, 0};
    int retSize = 0;
    int *q[3];
    for (int i = 0; i < 3; ++i) {
        q[i] = queries[i];
    }
    int queriesSize = 3;
    long long *ret = handleQuery(nums1, 3, nums2, 3, q, 3, &queriesSize, &retSize);
    for (int i = 0; i < retSize; ++i) {
        printf("%lld", ret[i]);
    }
}
